package cn.larry.common.utils.wx;

import cn.larry.common.utils.StringUtils;
import cn.larry.common.utils.http.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;

/**
 * This is created,
 * but not necessarily updated by me.
 * Therefore, AUTHOR is useless.
 * 2024/5/9
 * 微信公众号（微信用户）工具
 *
 * @Version 1.0
 */
@Slf4j
@Component
public class WxPublicTool {

    public static final String SNSAPI_BASE = "snsapi_base";
    public static final String SNSAPI_USERINFO = "snsapi_userinfo";

    /**
     * 请求微信重定向
     * 参考：https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html?_refluxos=a10#0
     *
     * @param response
     * @param appId       公众号的唯一标识
     * @param redirectUri 授权后重定向的回调链接地址， 无需使用 urlEncode 对链接进行处理
     * @param scope       默认"snsapi_userinfo"。应用授权作用域，snsapi_base （不弹出授权页面，直接跳转，只能获取用户openid），snsapi_userinfo （弹出授权页面，可通过openid拿到昵称、性别、所在地。并且， 即使在未关注的情况下，只要用户授权，也能获取其信息 ）
     * @param state       可为空。重定向后会带上state参数，开发者可以填写a-zA-Z0-9的参数值，最多128字节
     * @param logFlag     是否需要日志输出
     * @throws Exception
     */
    public void sendRedirect(HttpServletResponse response,
                             String appId,
                             String redirectUri,
                             String scope,
                             String state,
                             boolean logFlag) throws Exception {
        if (StringUtils.isEmpty(scope))
            scope = SNSAPI_USERINFO;

        String sendRedirectUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId
                + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8")
                + "&response_type=code&scope=" + scope;

        if (StringUtils.isEmpty(state))
            sendRedirectUrl += "&state=" + state;

        sendRedirectUrl += "#wechat_redirect";
        if (logFlag)
            log.info("sendRedirectUrl：{}", sendRedirectUrl);
        response.sendRedirect(sendRedirectUrl);
    }

    /**
     * 通过code换取网页授权access_token
     *
     * @param code   填写第一步获取的code参数
     * @param appid  公众号的唯一标识
     * @param secret 公众号的appsecret
     * @return
     */
    public String getAccessToken(String code,
                                 String appid,
                                 String secret) {
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appid
                + "&secret=" + secret
                + "&code=" + code
                + "&grant_type=authorization_code";
        return HttpUtils.sendGet(url);
    }

    /**
     * 刷新access_token
     *
     * @param appid        公众号的唯一标识
     * @param refreshToken 填写通过access_token获取到的refresh_token参数
     * @return
     */
    public String refreshAccessToken(String appid,
                                     String refreshToken) {
        String url = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=" + appid
                + "&grant_type=refresh_token&refresh_token=" + refreshToken;
        return HttpUtils.sendGet(url);
    }

    /**
     * 拉取用户信息(需scope为 snsapi_userinfo)
     *
     * @param openid      用户的唯一标识
     * @param accessToken 网页授权接口调用凭证,注意：此access_token与AppId基础支持的access_token不同
     * @return
     */
    public String getUserInfo(String openid, String accessToken) {
        String url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken
                + "&openid=" + openid + "&lang=zh_en";
        return HttpUtils.sendGet(url);
    }


}
